/*
 * Copyright 2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.oschina.durcframework.easymybatis.handler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

public class EnumTypeHandler<T,E extends Enum<?> & BaseEnum<T>> extends BaseTypeHandler<BaseEnum<T>> {
	private Class<E> clazz;

	public EnumTypeHandler(Class<E> enumType) {
		if (enumType == null)
			throw new IllegalArgumentException("Type argument cannot be null");

		this.clazz = enumType;
	}

	@Override
	public void setNonNullParameter(PreparedStatement ps, int i, BaseEnum<T> parameter, JdbcType jdbcType)
			throws SQLException {
		ps.setObject(i, parameter.getCode());
	}



	@Override
	public BaseEnum<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
		return parseValue(clazz, rs.getObject(columnName));
	}



	@Override
	public BaseEnum<T> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
		return parseValue(clazz, rs.getObject(columnIndex));
	}



	@Override
	public BaseEnum<T> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
		return parseValue(clazz, cs.getObject(columnIndex));
	}


	/**
	 * @param enumClass
	 * @param value
	 * @param <E>
	 * @return
	 */
	private static <T,E extends Enum<?> & BaseEnum<T>> E parseValue(Class<E> enumClass, Object value) {
		if(value == null) {
			return null;
		}
		E[] enumConstants = enumClass.getEnumConstants();
		for (E e : enumConstants) {
			if (e.getCode().toString().equals(value.toString()))
				return e;
		}
		return null;
	}

	
}